/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Symmetric Key Pair Class
 *      Represents and manages a symmetric encryption key and IV pair for a 
 * particular algorithm.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
using System;
using System.Security.Cryptography;

namespace Adaptive.Foundation.Security
{
    /// <summary>
    /// Represents and manages a symmetric encryption key and IV pair for a 
    /// particular algorithm.
    /// </summary>
    [Serializable()]
    public class SymmetricKeyPair : DisposableObjectBase
    {
        /*--------------------------------------------------------------------------------
         * Private Member Declarations
         *------------------------------------------------------------------------------*/
        #region Private Member Declarations
        /// <summary>
        /// Key value for use in a symmetric encryption/decryption algorithm.
        /// </summary>
        private byte[] _key;
        /// <summary>
        /// IV value for use in a symmetric encryption/decryption algorithm.
        /// </summary>
        private byte[] _iv;
        /// <summary>
        /// Algorithm the keys may be used by.
        /// </summary>
        private CryptographicAlgorithm _algorithm = CryptographicAlgorithm.None;
        #endregion

        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
        #region Constructor / Dispose / Destructor Methods
        /// <summary>
        /// Initializes a new instance of the to a set of new keys for the specified
        /// algorithm.
        /// </summary>
        /// <param name="algorithm">
        /// A <see cref="CryptographicAlgorithm"/> enumerated value indicating the type of 
        /// algorithm to which the keys belong.
        /// </param> 
        public SymmetricKeyPair(CryptographicAlgorithm algorithm)
            : base()
        {
            _algorithm = algorithm;
            _key = CryptoKeyFactory.GenerateKey(algorithm);
            _iv = CryptoKeyFactory.GenerateIV(algorithm);
        }
        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="keyValue">The value of the cryptographic key.</param>
        /// <param name="ivValue">The value of the cryptographic initialization vector.</param>
        /// <param name="algorithm">
        /// A <see cref="CryptographicAlgorithm"/> enumerated value indicating the type of 
        /// algorithm to which the keys belong.
        /// </param> 
        public SymmetricKeyPair(byte[] keyValue, byte[] ivValue, CryptographicAlgorithm algorithm)
            : base()
        {
            _key = keyValue;
            _iv = ivValue;
        }
        /// <summary>
        /// Deallocates internally allocated objects.
        /// </summary>
        /// <param name="disposing">
        /// A value indicating whether the object is being disposed.
        /// </param>
        protected override void Dispose(bool disposing)
        {
            if ((!Disposed) && (disposing))
            {
                Clear();
            }

            _iv = null;
            _key = null;
            base.Dispose(disposing);
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Properties
         *------------------------------------------------------------------------------*/
        #region Public Properties
        /// <summary>
        /// Gets or sets the byte array containing the cryptographic key value.
        /// </summary>
        /// <value>
        /// A byte array containing the key value used in a symmetric cryptographic algorithm.
        /// </value>
        public byte[] Key
        {
            get { return _key; }
            set
            {
                _key = value;
            }
        }
        /// <summary>
        /// Gets or sets the byte array containing the cryptographic initialization vector (IV) value.
        /// </summary>
        /// <value>
        /// A byte array containing the IV value used in a symmetric cryptographic algorithm.
        /// </value>
        public byte[] IV
        {
            get { return _iv; }
            set
            {
                _iv = value;
            }
        }
        /// <summary>
        /// Gets the algorithm the key and IV values are generated for.
        /// </summary>
        /// <value>
        /// A <see cref="CryptographicAlgorithm"/> enumerated value indicating the type of 
        /// algorithm to which the keys belong.
        /// </value>
        public CryptographicAlgorithm Algorithm
        {
            get { return _algorithm; }
        }
        #endregion

        /*--------------------------------------------------------------------------------
         * Public Methods / Functions
         *------------------------------------------------------------------------------*/
        #region Public Methods / Functions
        /// <summary>
        /// Clears the contents of the object instance without disposing of the instance.
        /// </summary>
        public void Clear()
        {
            if (_iv != null)
                Array.Clear(_iv, 0, _iv.Length);
            if (_key != null)
                Array.Clear(_key, 0, _key.Length);
        }
        #endregion
    }
}
